// ATTENTION
// This version doesn't work, what I tried to do is to have an AI spawn at the base, then run to the chopper, embark, do the taxi, then disembark at base and run back to the AI Spawn.
// I never could get the driver out of the vehicle and delete it... bummer. I need more XP I guess :)

// If something really wrong happens, we delete the AI driver and then we set the damage of the heli so that it it destroyed and spawns back to the base.
#define __del \
deleteVehicle _driver;\
_taxi_vehicle setDamage 1.1;

#define __deldriver \
_driver action ["getout",vehicle _driver];\
sleep 1;
deleteVehicle _driver;\

private ["_player", "_sidep", "_grp", "_vehicle", "_unit", "_crew", "_i", "_target_route","_taxi_vehicle","_vehicle_list","_crew_start_pos","_crew_board_pos","_last_pos","_driver"];
if (!isServer) exitWith {};

diag_log "Starting AirTaxiServer2";

// We can call this script in 3 ways:
// player call airtaxi
// [player,target] call airtaxi
// [player,[waypoint1, waypoint2, waypoint3]] call airtaxi
if (typename _this != "ARRAY") then {
	_player = _this;
} else {
	_player = _this select 0;
	If (count _this > 1) then {
		_target_route = _this select 1;
		// Now we check whether _target_route is a string (for fixed destinations) or one or more waypoints.
		if (typename _target_route == "STRING") then {
			// Until now only the 'BASE' string is used and the script defaults to returning to the base.
		} else {
			// We are in the case of one or more waypoints
			If (typename (_target_route select 0) != "ARRAY") then {
				// It is only 1 waypoint, so we need to enclose it in braces
				_target_route = [_target_route];
			};
		};
	};
};
_sidep = side _player;
_player_pos = getPos _player;

_crew_start_pos = d_pos_ai_spawn select 0;
_vehicle_list = nearestObjects [_crew_start_pos, [x_taxi_aircraft],300];
if (count _vehicle_list > 0) then { _taxi_vehicle = _vehicle_list select 0; };
if (isNil "_taxi_vehicle") exitWith { ["d_ataxi", [7,_player]] call XNetCallEvent; diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","No vehicle found"];};
_dstart_pos = getPos _taxi_vehicle;
_crew_board_pos = getPosASL _taxi_vehicle;
If (isNil "_target_route") then {
	_target_route = [_dstart_pos];
};
diag_log Format["** Route Positions:"];
{
	diag_log Format["   - %1",_x];
} foreach _target_route;
_last_pos = _target_route select ((count _target_route) - 1);
_last_pos = [_last_pos,typeof _taxi_vehicle,200] call XfFindLandingPosition;
_player_pos = [_player_pos,typeof _taxi_vehicle,200] call XfFindLandingPosition;
if (count _last_pos == 0) exitWith {["d_ataxi", [10,_player]] call XNetCallEvent; diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","The target position is not valid for landing"];};
if (count _player_pos == 0) exitWith {["d_ataxi", [10,_player]] call XNetCallEvent; diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","You are not standing in a valid zone for landing"];};
diag_log Format["(%1)[%2]: %3: %4, %5 (%6)",diag_tickTime,"airtaxiserver2.sqf","Calculated Pos",_target_route select (count _target_route - 1), _last_pos, isNil("XfFindLandingPosition")];

["airtaxi_available",False] call XNetSetJIP;

// 1. We create a Driver and get it next to the vehicle
_b_loop = isNil("_driver");
while { _b_loop } do {
	_grp = [_sidep] call x_creategroup;
	_crew_type = switch (_sidep) do {
			case west: {"USMC_Soldier_Pilot"};
			case east: {"RU_Soldier_Pilot"};
			default {"RU_Pilot"};
		};
	_driver = [_crew_type, _grp, _crew_start_pos] call XfCreateUnit;
	// _driver = _grp createUnit [_crew_type, _crew_start_pos, [], 0, "NONE"];
	_driver setVariable ["BIS_noCoreConversations", true];
	_driver setUnitAbility (0.9);
	// To avoid the aircraft to be a constant target while empty. When the players will be inside, it's another story :)
	// We make the grp cowards so it avoids engaging
	_grp allowFleeing 1;
	d_allunits_add set [count d_allunits_add, _driver];
	diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"airtaxiserver2.sqf","Driver created and moving to",_crew_board_pos];

	_i = 0;
	while {(_driver distance _taxi_vehicle > 15) And (alive _driver) And _i < 30 } do {
		_driver doMove _crew_board_pos;
		sleep 10;
		_i = _i + 1;
	};
	diag_log Format["(%1)[%2]: %3 (%4)(%5)",diag_tickTime,"airtaxiserver2.sqf","Driver moved",(position _driver),(position _taxi_vehicle)];
	
	if (!(alive _driver)) then {
		deleteVehicle _driver;
		sleep 5;
	} else {
		doStop _driver;
		sleep 0.5;
		_crew_board_pos = [(getPos _taxi_vehicle select 0) + 0.5, getPos _taxi_vehicle select 1, 0];
		if (_driver distance _taxi_vehicle > 3) then {
			_driver setPos _crew_board_pos;
			_driver MoveInDriver _taxi_vehicle;
			sleep 1;
		};
	};
	_b_loop = !(alive _driver);
};
diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","Driver next to vehicle"];

// 2. If the player died, we return to the driver to the AI Hut
if (!alive _player) exitWith {
	["d_ataxi", [1,_player]] call XNetCallEvent;
	sleep 120;
	[_driver,_dstart_pos] call XfReturnDriverToSpawn;
};

// 3. Otherwise we get the driver inside the vehicle.
_driver moveInDriver _taxi_vehicle;
//taxi_vehicle lockdriver true;
_driver setCaptive True;

// 4. We take off to the player position
diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","Starting vehicle"];
// 5. We check if the player is close to the airtaxi, if it's the case, he has to find it himself.
If (_player_pos distance _taxi_vehicle > 200) then {
	diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi departing to join the player"];
	[_taxi_vehicle, [_player_pos], 60, true, False] execVM "scripts\mando_heliroute_arma.sqf";

	sleep 10;
	_taxi_vehicle setfuel 1;
	// 5.1. We check if the player died, in such a case we return to the base and forget it.
	if (!alive _player) exitWith {
			["d_ataxi", [1,_player]] call XNetCallEvent;
			sleep 120;
			// Returning to the base
			[_taxi_vehicle, [_dstart_pos], 60, true] execVM "scripts\mando_heliroute_arma.sqf";
			While {(_taxi_vehicle getVariable "mando_heliroute" == "busy")} do {
				sleep 2;
			};
			_taxi_vehicle lockdriver false;
			_driver setCaptive False;
			[_driver,_dstart_pos] call XfReturnDriverToSpawn;
			["airtaxi_available",True] call XNetSetJIP;
		};

	["d_ataxi", [0,_player]] call XNetCallEvent;

	_toldp = false;
	while {_taxi_vehicle getVariable "mando_heliroute" == "busy"} do {
		if (_taxi_vehicle distance _player < 1000 && alive _player && !_toldp) then {
			["d_ataxi", [6,_player]] call XNetCallEvent;
			_toldp = true;
			sleep 1;
			["d_ataxi", [8,_player]] call XNetCallEvent;
		};
		sleep 2.012;
	};

	if (_taxi_vehicle getVariable "mando_heliroute" == "damaged") exitWith {
		["d_ataxi", [2,_player]] call XNetCallEvent;
		sleep 120;
		__del;
	};
} else {
	diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi waiting for the player"];
	_taxi_vehicle setVariable ["mando_heliroute","waiting"];
	["d_ataxi", [9,_player]] call XNetCallEvent;
	sleep 2;
	["d_ataxi", [8,_player]] call XNetCallEvent;
	sleep 5;
};
if (_taxi_vehicle getVariable "mando_heliroute" == "waiting") then {
	diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi waiting for the caller to get in"];
	while {alive _player && !(_player in crew _taxi_vehicle)} do {sleep 1.012};
	diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","Caller is inside the airtaxi"];
	if (alive _player) then {
		["d_ataxi", [3,_player]] call XNetCallEvent;	
		sleep 20 + random 5;
		["d_ataxi", [5,_player]] call XNetCallEvent;
		[_taxi_vehicle, _target_route, 60, true, ((_target_route select (count _target_route - 1)) distance _dstart_pos < 20)] execVM "scripts\mando_heliroute_arma.sqf";
		sleep 5;
		diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"airtaxiserver2.sqf","AirTaxi is on the way to target position",_target_route];
		while {_taxi_vehicle getVariable "mando_heliroute" == "busy"} do {sleep 2.012};
		if (_taxi_vehicle getVariable "mando_heliroute" == "damaged") exitWith {
			diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi was damaged"];
			["d_ataxi", [2,_player]] call XNetCallEvent;
			sleep 120;
			__del;
		};
		if (_taxi_vehicle getVariable "mando_heliroute" == "waiting") then {
			diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi has landed"];
			while {_player in crew _taxi_vehicle} do {sleep 3.012};
			diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","Player is out"];
			sleep 1 + random 5;
			["d_ataxi", [4,_player]] call XNetCallEvent;
			
			If (_taxi_vehicle distance _dstart_pos > 20) then {
				[_taxi_vehicle, [_dstart_pos], 60, true, true] execVM "scripts\mando_heliroute_arma.sqf";
				diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi on the way to start positon"];
				while {_taxi_vehicle getVariable "mando_heliroute" == "busy"} do {sleep 2.012};
				_taxi_vehicle setVariable ["mando_heliroute","landed"];
				_taxi_vehicle lockdriver false;
				_driver setCaptive False;
				sleep 10;
				diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","Stopped engines and leaving"];
				_driver = driver _taxi_vehicle;
				[_driver,_dstart_pos] call XfReturnDriverToSpawn;
				sleep 30;
			} else {
				diag_log Format["(%1)[%2]: %3 (%4,%5)",diag_tickTime,"airtaxiserver2.sqf","Stopping engines and leaving", typeOf _driver, typeof _taxi_vehicle];
				_taxi_vehicle setVariable ["mando_heliroute","landed"];
				_driver = driver _taxi_vehicle;
				for [{_i = 0}, {_i<10}, {_i=_i +1}] do {
					_driver action ["ENGINEOFF", _taxi_vehicle];
					sleep 1
				};
				_taxi_vehicle lockdriver false;
				_driver setCaptive False;
				sleep 5;
				[_driver,_dstart_pos] call XfReturnDriverToSpawn;
			};
		};
	} else {
		["d_ataxi", [1,_player]] call XNetCallEvent;
		sleep 120;
		[_taxi_vehicle, [_dstart_pos], 60, true] execVM "scripts\mando_heliroute_arma.sqf";
		diag_log Format["(%1)[%2]: %3",diag_tickTime,"airtaxiserver2.sqf","AirTaxi on the way to start positon"];
		While {(_taxi_vehicle getVariable "mando_heliroute" == "busy")} do {
			sleep 2;
		};
		_taxi_vehicle lockdriver false;
		_driver setCaptive False;
		sleep 10;
		[_driver,_dstart_pos] call XfReturnDriverToSpawn;
		sleep 30;
	};
};
["airtaxi_available",True] call XNetSetJIP;
